package com.bbcare.followup.plat.task;

import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.json.JSONArray;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.baidu.aip.ocr.AipOcr;
import com.bbcare.comm.AipOcrSingleton;
import com.bbcare.comm.DateUtil;
import com.bbcare.comm.PropertiesUtils;
import com.bbcare.followup.plat.service.IPictureOCRService;
import com.bbcare.followup.plat.store.ibatis.IPatientDAO;

import net.sf.json.JSONObject;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

/**
 * @name: 患者和图片匹配
 * @author: wuyz
 * @createTime: 2018.3
 * @description: 将患者和图片相关联
 * @modify:
 * 
 */
public class PatientMateImgTask implements Job {

	private final Log logger = LogFactory.getLog(PatientMateImgTask.class);

	@Autowired
	private IPictureOCRService pictureOCRService;

	@Autowired
	private IPatientDAO patientDao;
	
    @Resource
	private SqlSessionFactory sqlSessionFactory;

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		Map<String, Object> param = new HashMap<String, Object>();
		try {
			// 获取影像绑定接口url
			String imgCollection_url = PropertiesUtils.getProperty("imgCollection_url");
			// 获取百度云数据
			AipOcrSingleton Obj = AipOcrSingleton.getInstance();
			AipOcr client = Obj.getAipOcrClient();
			// 调用绑定接口入参
			Map<String, Object> mapIn = new HashMap<String, Object>();
			mapIn.put("URL", imgCollection_url);
			// 查询所有可以进行绑定的图像
			List<Map<String, Object>> list = pictureOCRService.GetOcrImgInfo(param);
			if (!CollectionUtils.isEmpty(list)) {
				for (int i = 0; i < list.size(); i++) {
					// 通过图片解析图文信息
					String paths = (String) list.get(i).get("file_path");
					String fileType = (String) list.get(i).get("file_type");
					//获取地址是否存在
					if(StringUtils.isBlank(paths)) {
						continue;
					}
					logger.info("paths");
					org.json.JSONObject jsons = pictureOCRService.pictureOCRCommon(paths,fileType,
							client);
					logger.info(jsons);
					if (jsons != null && jsons.length() > 0) {
						// 判断信息，通过图文信息查询用户信息
						Map<String, Object> map = JsonObjectCommon(jsons);
						if (StringUtils.isBlank((String) map.get("outPatienCard"))) {
							continue;
						}
						map.put("hisNo", map.get("outPatienCard"));
						map.put("tenantId", list.get(i).get("tenant_id"));
						map.put("userStatus", "1");
						List<Map<String,Object>> PatientList = patientDao.listPtArchInfoByCondition(map);
						// 查询到用户信息，进行用户和图像信息绑定，没有则继续循环
						if (!CollectionUtils.isEmpty(PatientList)) {
							Map<String,Object> pt = PatientList.get(0);
							String userId = (String) pt.get("id");
							String id = (String) list.get(i).get("id");
							String source_file_path = (String) list.get(i).get("source_file_path");
							mapIn.put("userId", userId);
							mapIn.put("id", id);
							mapIn.put("source_file_path", source_file_path);
							mapIn.put("birthday", pt.get("birthday"));
							mapIn.put("gender", pt.get("gender"));
							// 拼接入参函数
							String input = joinInput(mapIn);
							mapIn.put("xmlInfo", input);
							// 远程调用影像文件绑定接口
							String str = HttpUtils(mapIn);
							JSONObject json = JSONObject.fromObject(str);
							// 调用成功
							if (json.getBoolean("success")) {
								mapIn.put("id", id);
								updateAutoStatus(mapIn);
							} else {
								continue;
							}
						} else {
							continue;
						}
					}
				}
			}
		} catch (Exception e) {
			logger.info("查询失败");
			logger.info(e);
		}
	}

	// 远程调用图像绑定接口函数
	private String HttpUtils(Map<String, Object> mapIn) throws Exception {
		logger.info(mapIn.toString());
		String xmlInfo = (String) mapIn.get("xmlInfo");
		String URL = (String) mapIn.get("URL");
		byte[] xmlData = xmlInfo.getBytes();
		InputStream instr = null;
		try {
			URL url = new URL(URL);
			URLConnection urlCon = url.openConnection();
			urlCon.setDoOutput(true);
			urlCon.setDoInput(true);
			urlCon.setUseCaches(false);
			urlCon.setRequestProperty("Content-Type", "text/xml");
			urlCon.setRequestProperty("Content-length", String.valueOf(xmlData.length));
			// 设置超时时间
			urlCon.setConnectTimeout(30000);
			urlCon.setReadTimeout(30000);
			logger.info(String.valueOf(xmlData.length));
			DataOutputStream printout = new DataOutputStream(urlCon.getOutputStream());
			printout.write(xmlData);
			printout.flush();
			printout.close();
			instr = urlCon.getInputStream();
			byte[] bis = IOUtils.toByteArray(instr);
			String ResponseString = new String(bis, "UTF-8");
			if ((ResponseString == null) || ("".equals(ResponseString.trim()))) {
				logger.info("返回空");
			}
			logger.info("返回数据为:" + ResponseString);
			return ResponseString;

		} catch (Exception e) {
			return "0";
		} finally {
			try {
				instr.close();
			} catch (Exception ex) {
				return "0";
			}
		}
	}

	// 拼接调用绑定接口入参
	private String joinInput(Map<String, Object> map) throws Exception {
		// 用户+图片信息
		Map<String, Object> mapIn = new HashMap<String, Object>();
		// 操作信息
		Map<String, Object> oprInfo = new HashMap<String, Object>();

		if (map != null && map.size() > 0) {
			List<String> list = new ArrayList<String>();
			String source_file_path = (String) map.get("source_file_path");
			if(StringUtils.isNotBlank(source_file_path)) {
				list = selectImgByfilePath(map);
				map.put("queueId", matchQueueId(source_file_path));
			}else {
				list.add((String) map.get("id"));
			}
			map.remove("id");
			map.put("imgIdList", list);
			mapIn.put("assInfo", map);
		}
		oprInfo.put("opCode", "1116");
		oprInfo.put("opNote", "自动绑定用户和图片！");
		oprInfo.put("opType", "2");
		mapIn.put("oprInfo", oprInfo);
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("data", mapIn);

		// 将入参转换成json串
		JSONObject jsonObject = JSONObject.fromObject(data);
		return jsonObject.toString();
	}
	
	//判断队列信息
	private String matchQueueId(String path) throws Exception {
		String queueId= "";
		if(path.indexOf("上脸下垂")!=-1) {
			queueId = "12gzeyequeue001";
		}else if(path.indexOf("斜视")!=-1) {
			queueId = "12gzeyequeue002";
		}else if(path.indexOf("白内障")!=-1) {
			queueId = "12gzeyequeue003";
		}else if(path.indexOf("母细胞瘤")!=-1) {
			queueId = "12gzeyequeue004";
		}else if(path.indexOf("青光")!=-1) {
			queueId = "12gzeyequeue005";
		}else if(path.indexOf("早产儿")!=-1) {
			queueId = "12gzeyequeue006";
		}else if(path.indexOf("足月儿")!=-1) {
			queueId = "12gzeyequeue007";
		}else if(path.indexOf("眼底疾病")!=-1) {
			queueId = "12gzeyequeue008";
		}else if(path.indexOf("眼前段")!=-1) {
			queueId = "12gzeyequeue009";
		}
		return queueId;
	}
	
	
	//处理所有地址相同的图片
	private List<String> selectImgByfilePath(Map<String, Object> map) throws Exception {
		List<Map<String,Object>> lists= pictureOCRService.GetOcrImgInfo(map);
		List<String> listOut = new ArrayList<String>();
		if(CollectionUtils.isNotEmpty(lists)) {
			for(int i=0;i<lists.size();i++) {
				listOut.add((String)lists.get(i).get("id"));
			}
		}else {
			listOut.add((String) map.get("id"));
		}
		return listOut;
	}

	/**
	 * @author wuyz
	 * @date 2018-03-30
	 * @param json
	 *            解析解析图片返回的json信息
	 * 
	 **/
	public static Map<String, Object> JsonObject(org.json.JSONObject json) {
		Map<String, Object> map = new HashMap<String, Object>();
		if (json.getInt("error_code") == 0) {
			org.json.JSONObject data = json.getJSONObject("data");
			boolean isStructured = data.getBoolean("isStructured");
			if (isStructured) {
				JSONArray jsonArray = data.getJSONArray("ret");
				if (jsonArray != null && jsonArray.length() > 0) {
					for (int i = 0; i < jsonArray.length(); i++) {
						org.json.JSONObject jsons = jsonArray.getJSONObject(i);
						// 获得患者姓名
						if ("userName".equals(jsons.getString("word_name"))) {
							map.put("userName", jsons.getString("word"));
							// 获得门诊号
						} else if ("Outpatient".equals(jsons.getString("word_name"))) {
							map.put("Outpatient", jsons.getString("word"));
						}
					}
				}
				return map;
			}
		}
		return map;
	}
	
	
	/**
	 * @author wuyz
	 * @date 2018-03-30
	 * @param json
	 *  百度普通图文解析解析解析图片返回的json信息
	 * 
	 **/
	public static Map<String, Object> JsonObjectCommon(org.json.JSONObject json) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("outPatienCard", "");
		org.json.JSONObject jsonObject = null;
		if (json.getJSONArray("words_result")!=null) {
			org.json.JSONArray data = json.getJSONArray("words_result");
			if(data.length()>0) {
				for(int i =0;i<data.length();i++) {
					jsonObject = data.getJSONObject(i);
					String words =  jsonObject.getString("words");
					//处理数据，解析字符串中的数据，匹配连续16位数字并获取
					String  result = func(words);
					if(StringUtils.isNotBlank(result)) {
						map.put("outPatienCard", result);
						break;
					}
				}
			}
		}
		return map;
	}
	
	/**
	 * @author wuyz
	 * @date 2018-05-08
	 * @param json
	 *  百度普通图文解析解析解析图片返回的json信息
	 * 
	 **/
	public static  String func(String str) {
		Pattern p = Pattern.compile("\\d{16}");
		Matcher m = p.matcher(str);
		String result = m.find() ? m.group():null;
		return result;
	}

	//调用成功将auto_status更新成1
	@SuppressWarnings("unchecked")
	public void updateAutoStatus(Map<String,Object>mapIn) throws Exception {
		Map<String,Object> assInfo = (Map<String, Object>) mapIn.get("assInfo");
		List<String> imgIdList =  (List<String>) assInfo.get("imgIdList");
		String idList =  "";
		for(int i=0;i<imgIdList.size();i++) {
			if(i==imgIdList.size()-1) {
				idList = idList + "'"+imgIdList.get(i)+"'";
			}else {
				idList = idList + "'"+imgIdList.get(i)+"',";
			}
		}
		List<Object> paramList = null;
		List<List<Object>> updateList = new ArrayList<List<Object>>();
		paramList = new ArrayList<Object>();
		paramList.add(2);
		paramList.add(DateUtil.getSysDateA());
		paramList.add(2);
		paramList.add(idList);
		updateList.add(paramList);
		int success = 1;
		String sql = "update ai_img_info a  set a.auto_status =? ,a.update_time =? ,a.confirm_status =? where a.id in (?) ";
		int[] arr = updateBatch(sql, updateList);
		for (int j = 0; j < arr.length; j++) {
			if (success == arr[j]) {
				logger.info("更新图像表auto_status--[" + mapIn.get("id") + "]");
			} else {
				logger.info("更新图像表auto_status失败，被其他线程或应用处理--[" + mapIn.get("id") + "]");
			}
		}
	}
	
	 //执行更新操作
	@Transactional
	public int[] updateBatch(String sql, List<List<Object>> list) throws Exception {
		SqlSession sqlSession = sqlSessionFactory.openSession();
	    PreparedStatement pstm = null;
	    int[] re = null;
	    try {
	    	Connection con = sqlSession.getConnection();
	        pstm = con.prepareStatement(sql);
			for (List<Object> blist : list) {
				for (int i = 0; i < blist.size(); i++) {
					pstm.setObject(i + 1, blist.get(i));
				}
				pstm.addBatch();
			}
			re = pstm.executeBatch();
	      }
	      catch(Exception e) {
	        logger.error("", e);
	        throw e;
	      }
	      finally {
	        if(pstm != null)
	        	pstm.close();
	        	sqlSession.close();
	      }
		return re;
	}
}
